home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / The Hacks! / Interim Executive Decision / Steve.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-21  |  7.1 KB  |  479 lines  |  [TEXT/CWIE]

  1. /*
  2.  *  pSmallDaemon
  3.  *
  4.  *  7/92 Greg Robbins         based on code by C.K. Haun
  5.  *
  6.  *  This is a minimal faceless background application for System 7.
  7.  *
  8.  *  It demonstrates how to install and dispatch Apple events, as well
  9.  *  as the other bare essentials for a faceless background app.
  10.  *
  11.  *  The file type for this application should be 'APPL' if it will be launched
  12.  *  like an application or 'appe' if it will be placed into the Extensions
  13.  *  folder and launched at startup.  'appe' files can also have an INIT resource 
  14.  *  to put up an icon (using ShowInit) at startup.
  15.  */
  16.  
  17.  
  18. #include <AppleEvents.h>
  19. #include <AERegistry.h>
  20.  
  21. #include <Errors.h>
  22. #include <Gestalt.h>
  23. #include <Memory.h>
  24. #include <Resources.h>
  25. #include <TextUtils.h>
  26. #include <Types.h>
  27.  
  28. #define kSleepMax 0
  29.  
  30. // Global Variables
  31.  
  32. Boolean        gQuitFlag = false;
  33. Boolean        gAppleEventsFlag = true;
  34. long        gSleepVal = 0;
  35. OSErr        gRetCode = noErr;
  36. long        gGestResponse = 0;
  37. EventRecord    gMainEventRec;
  38. Boolean        gEventFlag = false;
  39.  
  40. // Code resource routines.
  41.  
  42. typedef    pascal void* (*tCodeFrag)(int iRoutineSelector);
  43.  
  44. typedef CALLBACK_API( OSErr , RegisterFunctionProcPtr )(OSType selector, long response);
  45. typedef STACK_UPP_TYPE(RegisterFunctionProcPtr) RegisterFunctionUPP;
  46.  
  47. SelectorFunctionUPP gFindSelector = nil;
  48. RegisterFunctionUPP gRegisterSelector = nil;
  49.  
  50. //    { Apple event handlers to be installed }
  51.  
  52. static
  53. pascal
  54. OSErr
  55. DoAEOpenApplication
  56. (
  57.     const AppleEvent*    theEvent,
  58.     AppleEvent* theReply,
  59.     long refcon
  60. );
  61.  
  62. static
  63. pascal
  64. OSErr
  65. DoAEOpenApplication
  66. (
  67.     const AppleEvent*    theEvent,
  68.     AppleEvent* theReply,
  69.     long refcon
  70. )
  71. {
  72.     OSErr            err = noErr;
  73.     return err;
  74. }
  75.         
  76. static
  77. pascal
  78. OSErr
  79. DoAEOpenDocuments
  80. (
  81.     const AppleEvent*    theEvent,
  82.     AppleEvent* theReply,
  83.     long refcon
  84. );
  85.  
  86. static
  87. pascal
  88. OSErr
  89. DoAEOpenDocuments
  90. (
  91.     const AppleEvent*    theEvent,
  92.     AppleEvent* theReply,
  93.     long refcon
  94. )
  95. {
  96.     OSErr            err = noErr;
  97.     return err;
  98. }
  99.         
  100. static
  101. pascal
  102. OSErr
  103. DoAEPrintDocuments
  104. (
  105.     const AppleEvent*    theEvent,
  106.     AppleEvent* theReply,
  107.     long refcon
  108. );
  109.  
  110. static
  111. pascal
  112. OSErr
  113. DoAEPrintDocuments
  114. (
  115.     const AppleEvent*    theEvent,
  116.     AppleEvent* theReply,
  117.     long refcon
  118. )
  119. {
  120.     OSErr            err = noErr;
  121.     return err;
  122. }
  123.         
  124. static
  125. pascal
  126. OSErr
  127. DoAEQuitApplication
  128. (
  129.     const AppleEvent*    theEvent,
  130.     AppleEvent* theReply,
  131.     long refcon
  132. );
  133.  
  134. static
  135. pascal
  136. OSErr
  137. DoAEQuitApplication
  138. (
  139.     const AppleEvent*    theEvent,
  140.     AppleEvent* theReply,
  141.     long refcon
  142. )
  143. {
  144.     OSErr            err = noErr;
  145.     gQuitFlag = true;
  146.     return err;
  147. }
  148.  
  149. static
  150. pascal
  151. OSErr
  152. DoAESteve
  153. (
  154.     const AppleEvent*    theEvent,
  155.     AppleEvent* theReply,
  156.     long refcon
  157. );
  158.  
  159. static
  160. pascal
  161. OSErr
  162. DoAESteve
  163. (
  164.     const AppleEvent*    theEvent,
  165.     AppleEvent* theReply,
  166.     long refcon
  167. )
  168. {
  169.     OSErr            err = noErr;
  170.     OSType            selector;
  171.     OSType            actualType;
  172.     Size            actualSize;
  173.     long            value = 0;
  174.     long            patchIndex = -1;
  175.  
  176.     err =
  177.         AEGetParamPtr
  178.         (
  179.             theEvent,
  180.             keyDirectObject,
  181.             typeType,
  182.             &actualType,
  183.             &selector,
  184.             sizeof(selector),
  185.             &actualSize
  186.         );
  187.  
  188.     if (err == noErr)
  189.     {
  190.         err =
  191.             AEGetParamPtr
  192.             (
  193.                 theEvent,
  194.                 'ARF ',
  195.                 typeLongInteger,
  196.                 &actualType,
  197.                 &value,
  198.                 sizeof(value),
  199.                 &actualSize
  200.             );
  201.     }
  202.  
  203.     if (err == noErr)
  204.     {
  205.         err = gRegisterSelector(selector, value);
  206.     }
  207.  
  208.     if (err == noErr)
  209.     {
  210.         err =
  211.             AEPutParamPtr
  212.             (
  213.                 theReply,
  214.                 keyAEResult,
  215.                 typeLongInteger,
  216.                 &value,
  217.                 sizeof(value)
  218.             );
  219.     }
  220.  
  221.     return err;
  222. }
  223.         
  224. static
  225. pascal
  226. OSErr
  227. DoAEGetGestalt
  228. (
  229.     const AppleEvent*    theEvent,
  230.     AppleEvent* theReply,
  231.     long refcon
  232. );
  233.  
  234. static
  235. pascal
  236. OSErr
  237. DoAEGetGestalt
  238. (
  239.     const AppleEvent*    theEvent,
  240.     AppleEvent* theReply,
  241.     long refcon
  242. )
  243. {
  244.     OSErr            err = noErr;
  245.     OSType            selector;
  246.     OSType            actualType;
  247.     Size            actualSize;
  248.     long            response = 0;
  249.     long            patchIndex = -1;
  250.  
  251.     err =
  252.         AEGetParamPtr
  253.         (
  254.             theEvent,
  255.             keyDirectObject,
  256.             typeType,
  257.             &actualType,
  258.             &selector,
  259.             sizeof(selector),
  260.             &actualSize
  261.         );
  262.  
  263.     if (err == noErr)
  264.     {
  265.         err = Gestalt(selector, &response);
  266.     }
  267.  
  268.     if (err == noErr)
  269.     {
  270.         err =
  271.             AEPutParamPtr
  272.             (
  273.                 theReply,
  274.                 keyAEResult,
  275.                 typeMagnitude,
  276.                 &response,
  277.                 sizeof(response)
  278.             );
  279.     }
  280.  
  281.     return err;
  282. }
  283.         
  284. static
  285. pascal
  286. void
  287. InitAppleEventsStuff
  288. (
  289. )
  290. {
  291.     OSErr        retCode = noErr;
  292.  
  293.     if (gAppleEventsFlag)
  294.     {
  295.         retCode =
  296.             AEInstallEventHandler
  297.             (
  298.                 kCoreEventClass,
  299.                 kAEOpenApplication,
  300.                 (AEEventHandlerUPP)DoAEOpenApplication,
  301.                 0,
  302.                 false
  303.             );
  304.  
  305.         if (retCode == noErr)
  306.         {
  307.             retCode =
  308.                 AEInstallEventHandler
  309.                 (
  310.                     kCoreEventClass,
  311.                     kAEOpenDocuments,
  312.                     (AEEventHandlerUPP)DoAEOpenDocuments,
  313.                     0,
  314.                     false
  315.                 );
  316.         }
  317.  
  318.         if (retCode == noErr)
  319.         {
  320.             retCode =
  321.                 AEInstallEventHandler
  322.                 (
  323.                     kCoreEventClass,
  324.                     kAEPrintDocuments, 
  325.                     (AEEventHandlerUPP)DoAEPrintDocuments,
  326.                     0,
  327.                     false
  328.                 );
  329.         }
  330.  
  331.         if (retCode == noErr)
  332.         {
  333.             retCode =
  334.                 AEInstallEventHandler
  335.                 (
  336.                     kCoreEventClass,
  337.                     kAEQuitApplication,
  338.                     (AEEventHandlerUPP)DoAEQuitApplication,
  339.                     0,
  340.                     false
  341.                 );
  342.         }
  343.  
  344.         if (retCode == noErr)
  345.         {
  346.             retCode =
  347.                 AEInstallEventHandler
  348.                 (
  349.                     'SPJ!',
  350.                     'SPJ!',
  351.                     (AEEventHandlerUPP)DoAESteve,
  352.                     0,
  353.                     false
  354.                 );
  355.         }
  356.  
  357.         if (retCode == noErr)
  358.         {
  359.             retCode =
  360.                 AEInstallEventHandler
  361.                 (
  362.                     'SPJ!',
  363.                     'GetG',
  364.                     (AEEventHandlerUPP)DoAEGetGestalt,
  365.                     0,
  366.                     false
  367.                 );
  368.         }
  369.  
  370.         if (retCode != noErr)
  371.         {
  372.             DebugStr("\pInstall event handler failed");
  373.         }
  374.     }
  375. }
  376.  
  377. static
  378. pascal
  379. OSErr
  380. DoHighLevelEvent
  381. (
  382.     const EventRecord*    theEventRec
  383. )
  384. {
  385.     OSErr             retCode = noErr;
  386.  
  387.     retCode = AEProcessAppleEvent(theEventRec);
  388.     return retCode;
  389. }
  390.  
  391. void main()
  392. {
  393.     Handle            codeFrag = nil;
  394.     tCodeFrag        fragMain;
  395.     Size            fragSize;
  396.  
  397. /*    
  398.     faceless background apps only get a 2K stack by default.  If necessary,
  399.     increase the stack size here (by calling GetApplLimit to find the current
  400.     heap limit, and SetApplLimit to set it to a lower address, thus reserving
  401.     more space for the stack)
  402. */
  403.  
  404. //    { initialize QuickDraw globals }
  405.     
  406.     InitGraf(qd.thePort);
  407.     
  408. //    { initialize application globals }
  409.     
  410.     gQuitFlag = false;
  411.     gSleepVal = kSleepMax;
  412.     
  413. //    { is the Apple Event Manager available? }
  414.     
  415.     gRetCode = Gestalt(gestaltAppleEventsAttr, &gGestResponse);
  416.  
  417.     if ((gRetCode == noErr) && (gGestResponse & (1L << gestaltAppleEventsPresent)))
  418.     {
  419.         gAppleEventsFlag = true;
  420.     }
  421.     else
  422.     {
  423.         gAppleEventsFlag = false;
  424.     }
  425.  
  426. //    { install Apple event handlers }
  427.     
  428.     InitAppleEventsStuff();
  429.  
  430. // Set up the code resource.
  431.  
  432.     codeFrag = GetResource('ARF!', 128);
  433.     gRetCode = ResError();
  434.  
  435.     if (codeFrag && (gRetCode == noErr))
  436.     {
  437.         fragSize = GetHandleSize(codeFrag);
  438.         fragMain = (tCodeFrag)NewPtrSys(fragSize);
  439.  
  440.         gRetCode = MemError();
  441.     }
  442.  
  443.     if (gRetCode == noErr)
  444.     {
  445.         BlockMoveData(*codeFrag, fragMain, fragSize);
  446.         FlushInstructionCache();
  447.         gFindSelector = fragMain(0);
  448.         gRegisterSelector = fragMain(1);
  449.     }
  450.  
  451.     if (codeFrag)
  452.     {
  453.         ReleaseResource(codeFrag);
  454.     }
  455.  
  456.     if ((!gFindSelector) || (!gRegisterSelector))
  457.     {
  458.         gQuitFlag = true;
  459.     }
  460.  
  461. //    { main event loop }
  462.  
  463.     while (!gQuitFlag)
  464.     {
  465.         gEventFlag = 
  466.             WaitNextEvent(highLevelEventMask, &gMainEventRec, gSleepVal, nil);
  467.  
  468. //        { faceless background tasks receive only high-level events }
  469.         if (gMainEventRec.what == kHighLevelEvent)
  470.         {
  471.             DoHighLevelEvent(&gMainEventRec);
  472.         }
  473.  
  474. //        { during testing, I like to call GetKeys here and check if the CapsLock
  475. //          key is down.  If it is, set gQuitFlag so the program will exit. }
  476.     }
  477.  
  478. }
  479.